package com.leyou.common.auth.utils;

import com.leyou.common.auth.entity.Payload;
import com.leyou.common.auth.entity.UserInfo;
import com.leyou.common.utils.JsonUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.joda.time.DateTime;

import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Base64;
import java.util.UUID;


public class JwtUtils {

    private static final String JWT_PAYLOAD_USER_KEY = "user";

    /**
     * 私钥加密token
     *
     * @param userInfo   载荷中的数据
     * @param privateKey 私钥
     * @param expire     过期时间，单位分钟
     * @return JWT
     */
    public static String generateTokenExpireInMinutes(Object userInfo, PrivateKey privateKey, int expire) {
        return Jwts.builder()
                .claim(JWT_PAYLOAD_USER_KEY, JsonUtils.toString(userInfo))
                .setId(createJTI())
                .setExpiration(DateTime.now().plusMinutes(expire).toDate())
                .signWith(privateKey, SignatureAlgorithm.RS256)
                .compact();
    }

    /**
     * 私钥加密token
     *
     * @param userInfo   载荷中的数据
     * @param privateKey 私钥
     * @param expire     过期时间，单位秒
     * @return JWT
     */
    public static String generateTokenExpireInSeconds(Object userInfo, PrivateKey privateKey, int expire) {
        return Jwts.builder()
                .claim(JWT_PAYLOAD_USER_KEY, JsonUtils.toString(userInfo))
                .setId(createJTI())
                .setExpiration(DateTime.now().plusSeconds(expire).toDate())
                .signWith(privateKey, SignatureAlgorithm.RS256)
                .compact();
    }

    /**
     * 公钥解析token
     *
     * @param token     用户请求中的token
     * @param publicKey 公钥
     * @return Jws<Claims>
     */
    private static Jws<Claims> parserToken(String token, PublicKey publicKey) {
        return Jwts.parser().setSigningKey(publicKey).parseClaimsJws(token);
    }

    private static String createJTI() {
        return new String(Base64.getEncoder().encode(UUID.randomUUID().toString().getBytes()));
    }

    /**
     * 获取token中的用户信息
     *
     * @param token     用户请求中的令牌
     * @param publicKey 公钥
     * @return 用户信息
     */
    public static <T> Payload<T> getInfoFromToken(String token, PublicKey publicKey, Class<T> userType) {
        Jws<Claims> claimsJws = parserToken(token, publicKey);
        Claims body = claimsJws.getBody();
        Payload<T> claims = new Payload<>();
        claims.setId(body.getId());
        claims.setUserInfo(JsonUtils.toBean(body.get(JWT_PAYLOAD_USER_KEY).toString(), userType));
        claims.setExpiration(body.getExpiration());
        return claims;
    }

    /**
     * 获取token中的载荷信息
     *
     * @param token     用户请求中的令牌
     * @param publicKey 公钥
     * @return 用户信息
     */
    public static <T> Payload<T> getInfoFromToken(String token, PublicKey publicKey) {
        Jws<Claims> claimsJws = parserToken(token, publicKey);
        Claims body = claimsJws.getBody();
        Payload<T> claims = new Payload<>();
        claims.setId(body.getId());
        claims.setExpiration(body.getExpiration());
        return claims;
    }

    public static void main(String[] args) throws Exception{
//        1、加密--产生token字符串
//        p1 :UserInfo  p2: 私钥   p3：失效时间
//        UserInfo userInfo = new UserInfo(10L,"zhangsan","vip");
//        PrivateKey privateKey = RsaUtils.getPrivateKey("D:\\class118-leyou\\id_rsa");
//        String token = JwtUtils.generateTokenExpireInMinutes(userInfo, privateKey, 30);//产生的token1分钟后就失效了
//        System.out.println(token);
//     2、解密--根据token字符解密
//        String token = "eyJhbGciOiJSUzI1NiJ9.eyJ1c2VyIjoie1wiaWRcIjoxMCxcInVzZXJuYW1lXCI6XCJ6aGFuZ3NhblwiLFwicm9sZVwiOlwidmlwXCJ9IiwianRpIjoiTVRabU5EWmxORE10TVdGaFlpMDBObVJrTFRreU1UTXRaRFJqWm1NNVpUSmhPREU0IiwiZXhwIjoxNTgyNjg0MzM4fQ.l_1Pw5tYi8FhUlCTKz-RsQjTyRFGcklcT_4lwjBvufhfcWgvfdT2d11cONg2CdenIFT9y4cuWvwKqu3JWtvqAsDT6BP_E1-P3H1w1eEexMJ3DRwZhNAUOIrXNQSoiZJYb8WPdURKA2ZaMTtIbY9kXn6z6F5WB6Ez0ZvUPyST73WV054rPvlMfqrDNCQ9Lc26IMubU88lwbNSkSPj_CtcisT7FDRg18QofpLImuwjdn8tR_X6739-NnddWC82mbQDwKKfwPxsTBrFXiYNmO226ZkL_J2QvGORD3QAA5KnAn75WxDnJJihXlmo9Wx-DKODB4LZfjBZ-Sfi-jigRhF6UQ";
        String token="eyJhbGciOiJSUzI1NiJ9.eyJ1c2VyIjoie1wiaWRcIjoxMCxcInVzZXJuYW1lXCI6XCJ6aGFuZ3NhblwiLFwicm9sZVwiOlwidmlwXCJ9IiwianRpIjoiWXpNNU1HTm1PVE10TVdZek5DMDBNV1JtTFRnd09EUXRNbVJtWVdNeU5EazFZV0UyIiwiZXhwIjoxNTgyNjg2MTc3fQ.hylvVitQh2mqQtRf7C_siIYCryz0DGhdjXsYDXF8wSitxE4MRl1Ua7uwZb8N6kluiIEoEvfX2ZBicYc6bpyHIti7c9AQW-tFp-l9QgGLo4dG7jv2xISIIRO9rbK6bpnWTJvpZN38Wt4CLQEsJN3P0bRNJgQ3QhBViWrf9VeMik4-NdQWla2-DO8wUFCAInnrDgUnNqxM1qQOcMCYfoByswrJnpXvjPrXYFUiULRuOqTf6PxgR8n-jraMSQt-r-AhNhxrq8990MKMp7yHDflCdwAFBtUyX5TPG8AdcZfWy83q28hajQEUCViuFOJ_9_k0iDSZPQuXt6Z1vbrfoD14yQ";
        //            p1: token  p2: 公钥  p3: 类型
        PublicKey publicKey = RsaUtils.getPublicKey("D:\\class118-leyou\\id_rsa.pub");
        Payload<UserInfo> payload = JwtUtils.getInfoFromToken(token, publicKey, UserInfo.class);
        System.out.println(payload.getUserInfo());

    }


}
